#include "stdafx.h"
#include "TypeDNCU.h"
TypeDNCU::TypeDNCU():
GeneralNCU(TypeD)
{
}
TypeDNCU::TypeDNCU(const unsigned int &config):
GeneralNCU(TypeD,config), TypeANCU(config)
{
}
TypeDNCU::TypeDNCU(const unsigned int &config,
				   const vector<double> &paras):
GeneralNCU(TypeD,config), TypeANCU(config)
{
	parameters(paras);
}

TypeDNCU::TypeDNCU(const TypeDNCU &rhs):
GeneralNCU(rhs), TypeANCU(rhs)
{
	m_SingleVent = rhs.m_SingleVent;
	m_interVent = rhs.m_interVent;
}
TypeDNCU& TypeDNCU::operator=(const TypeDNCU &rhs)
{
	if ( this != &rhs)
	{
		TypeANCU::operator =(rhs);
		m_SingleVent = rhs.m_SingleVent;
		m_interVent = m_interVent;
	}
	return (*this);
}
TypeDNCU::~TypeDNCU()
{
}
/*********************************************
	Configuration Section
*********************************************/
// get the number of parameters of a NCU
const unsigned int TypeDNCU::number() const
{
	return ((2*nSequence())+ 3);
}
/*********************************************
	Parameters Section
*********************************************/
// assign all parametrs of a NCU
bool TypeDNCU::parameters(const vector<double> &paras)
{
	if ( paras.size() != number() )
	{
		errMsg = msg[2];
		return false;
	}
	else
	{
		vector<double>::const_iterator iter = paras.begin();
		initialSill(*iter);  // assign the value of the initial sill
		reset(); // set the value of the current sill to the value of the initial sill
		++ iter;
		m_interVent.VentCoe(*iter); // assign the value of the intermediate single vent
		++ iter;
		m_SingleVent.VentCoe(*iter); // assign the singel vent
		++ iter;
		vector<double> tmp(iter, paras.end());
		sequence(tmp); // assign the values of the sequence of the lateral output
		return true;
	}
}
// get all parameters of a NCU
vector<double> TypeDNCU::parameters() const
{
	vector<double> paras, tmp;
	paras.push_back(TypeANCU::initialSill());
	paras.push_back(
		m_interVent.VentCoe()
		);
	paras.push_back(
		m_SingleVent.VentCoe()
		);
	tmp = TypeANCU::sequence().parameters();
	paras.insert(paras.end(), tmp.begin(), tmp.end());
	return paras;
}
// virtual constructor
GeneralNCU* TypeDNCU::clone() const
{
	return new TypeDNCU(*this);
}
// simulation
outputPair TypeDNCU::simulation(const double &input)
{
	update(input);
	outputPair flow;
	flow.first = TypeBNCU::output(currentSill());
	flow.second = TypeCNCU::bottom(currentSill());
	currentSill(
		currentSill() - flow.first-flow.second
		);
	return flow;
}
// get the genome information
vector<const GenomeType*> TypeDNCU::genome() const
{
	vector <const GenomeType*> tmp;
	tmp.push_back(&genomeSet().GetVentGenome()); // CISV
	tmp.push_back(&genomeSet().GetVentGenome()); // CSV
	vector<const GenomeType*> info = TypeANCU::genome();
	vector<const GenomeType*>::iterator loc = info.begin();
	++loc;
	info.insert(loc, tmp.begin(), tmp.end());
	return info;
}